package com.nexgo.payment.trans.detail;

import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;

import com.nexgo.oaf.apiv3.SdkResult;
import com.nexgo.payment.App;
import com.nexgo.payment.R;
import com.nexgo.payment.aop.annotation.RunOnMainThread;
import com.nexgo.payment.constrant.PreferencesConstants;
import com.nexgo.payment.constrant.TransType;
import com.nexgo.payment.databases.DataSource;
import com.nexgo.payment.databases.TransRecord;
import com.nexgo.payment.util.PrintHelper;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * 交易详情相关操作
 *
 * @author 谭忠扬-YuriTam
 * @time 2017年08月14日
 */
public class TransDetailPresenter implements TransDetailContract.Presenter {
    private Logger mLog = LoggerFactory.getLogger(TransDetailPresenter.class.getSimpleName());

    private TransDetailContract.View mView;
    private DataSource mRepository;
    private String mTraceNum;
    private TransRecord mTransRecord;
    private int mPrintTimes = 0;  //记录当前打印次数
    private VOID_STATE mState;
    private boolean mIsFirstTimes = true;
    private boolean mIsAutoPrint = false;

    public TransDetailPresenter(@NonNull TransDetailContract.View view, @NonNull DataSource repository, @NonNull String traceNum) {
        mView = checkNotNull(view);
        mRepository = checkNotNull(repository);
        mTraceNum = checkNotNull(traceNum);
        mView.setPresenter(this);
        mState = VOID_STATE.INIT;
    }

    @Override
    public void start() {
        if (mIsFirstTimes) {
            mIsFirstTimes = false;
            //默认查询最后一笔记录并开始打印
            if ("000000".equals(mTraceNum)) {
                setIsAutoPrint(true);
                mTransRecord = mRepository.getLastSuccessfulTransRecord();
                if (mTransRecord == null) {
                    postMainThread(() -> mView.showNoTransRecord());
                    return;
                }
                postMainThread(() -> mView.onTransReceived(mTransRecord));
                //开始打印
                new Handler(Looper.myLooper()).postDelayed(() -> startPrint(), 200);
                return;
            }
        }
        mLog.debug("根据流水号查询交易记录");
        //根据凭证号查询流水记录
        mTransRecord = mRepository.queryTransRecord(mTraceNum);
        if (mTransRecord == null || !mTransRecord.getIsSuccess()) {
            postMainThread(() -> mView.showTransNotExist());
            return;
        }
        if (mState == VOID_STATE.PRE_CHANGE && mTransRecord.getIsVoid()) {
            mState = VOID_STATE.IS_CHANGE;
        }
        postMainThread(() -> mView.onTransReceived(mTransRecord));
    }

    @Override
    public void pause() {

    }

    @Override
    public void destroy() {

    }

    @Override
    public void doVoidByTransType() {
        TransType transType = TransType.values()[mTransRecord.getTransType()];
        switch (transType) {
            case SALE:
                postMainThread(() -> mView.showSaleVoid(mTransRecord.getTraceNum()));
                break;
            case SCAN_SALE:
            case SCAN_ORDER:
                postMainThread(() -> mView.showScanSaleVoid(mTransRecord.getPayTraceCode()));
                break;
            case AUTH_CM:
                postMainThread(() -> mView.showAuthComVoid(mTransRecord.getTraceNum()));
                break;
            default:
                break;
        }
        mState = VOID_STATE.PRE_CHANGE;
    }

    @Override
    public boolean getIsChange() {
        return mState == VOID_STATE.IS_CHANGE;
    }

    @Override
    public void startPrint() {
        //获取总打印联数
        int totalTimes = Integer.parseInt(mRepository.getParamValue(PreferencesConstants.PRINT_TIMES));
        if (totalTimes == 0 || mPrintTimes == totalTimes) return;
        //初始化打印机
        int result = PrintHelper.printerCfgInit();
        if (result != SdkResult.Success) {
            postMainThread(() -> mView.showPrintInitErr());
            return;
        }
        //判断打印机是否缺纸
        if (PrintHelper.isPaperLack()) {
            postMainThread(() -> mView.showPrintLackPaper());
            return;
        }
        PrintHelper.formPrintTransData(mTransRecord, mPrintTimes, totalTimes, true);
        //开始打印
        postMainThread(() -> mView.setPrintingIndicator(true));
        PrintHelper.startPrint(true, retCode -> {
            postMainThread(() -> mView.setPrintingIndicator(false));
            switch (retCode) {
                case SdkResult.Success:
                    if (mPrintTimes == 0) {
                        mTransRecord.setIsPrinted(true);
                        mRepository.updateTransRecord(mTransRecord);
                    }
                    ++mPrintTimes;
                    if (mPrintTimes < totalTimes) {
                        postMainThread(() -> mView.showConfirmPrintAgain());
                        return;
                    }
                    if (mPrintTimes == totalTimes) {
                        postMainThread(() -> mView.showPrintSuccess());
                        return;
                    }
                    postMainThread(() -> mView.showPrintSuccess());
                    break;
                case SdkResult.Printer_PaperLack:
                    postMainThread(() -> mView.showPrintLackPaper());
                    break;
                default:
                    postMainThread(() -> mView.showPrintFail(App.sContext.getString(R.string.print_fail)));
                    break;
            }
        });
    }

    public boolean isAutoPrint() {
        return mIsAutoPrint;
    }

    public void setIsAutoPrint(boolean mIsAutoPrint) {
        this.mIsAutoPrint = mIsAutoPrint;
    }

    @RunOnMainThread
    private void postMainThread(Runnable runnable) {
        runnable.run();
    }

    enum VOID_STATE {
        INIT,
        PRE_CHANGE,
        IS_CHANGE
    }
}
